// https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/longest-substring-without-repeating-characters-b-2/
// 滑动窗口

int lengthOfLongestSubstring(string str)
{
  // 记录最大无重复子串【开始下标】
  int start = 0;

  // 记录最大无重复子串【最大长度】
  int max_len = 0;

  // 记录每一个字符 str[i] 当后面出现【重复】时，滑动窗口的【起始 start】应该【调整到】的新位置
  // - key: 字符值
  // - value: 调整到的 新位置
  // map<char,int> hash;
  vector<int> hash(128, 0); // hash[i] 表示 `字符(ascii值为 i)` 下次调整到的位置

  // 遍历字符串
  for (int j = 0; j < str.size(); j++)
  {
    // 1. 获取 当前 `字符 str[j]` 要调整到的【最大】位置
    // - str[j] 字符串 str 中 j 下标对应的 字符
    // - hash[str[j]] 字符 str[j] 出现重复时，当前 i 要调整到的新位置，默认为 0
    start = max(start, hash[str[j]]);

    // 2. 更新 当下一次 遇到 str[j] 字符时 start 要调整到 j + 1 的位置
    hash[str[j]] = j + 1;

    // 3. 不断的记录 当前最大【无重复】字符串的【长度】
    max_len = max(max_len, (j - start + 1));
  }

  return max_len;
}